package cn.mjnxin.iot.connector.connector;

import java.util.concurrent.TimeUnit;

import cn.mjnxin.iot.base.constant.ConstantValue;
import cn.mjnxin.iot.base.log.LogWorker;
import cn.mjnxin.iot.base.util.CommonUtil;
import cn.mjnxin.iot.connector.coder.Gate2HostDecoder;
import cn.mjnxin.iot.connector.coder.Host2GateEncoder;
import cn.mjnxin.iot.connector.context.ConnectorContext;
import cn.mjnxin.iot.connector.context.IPeerContext;
import cn.mjnxin.iot.connector.handle.ConnectorAsServer4GateInHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * 前置作为服务端连网关
 * 
 * @author CLG 2023年10月10日
 * @version V1.0.0
 */
public class ConnectorAsServer4Gate {
    private EventLoopGroup  work = new NioEventLoopGroup();
    private EventLoopGroup  boss = new NioEventLoopGroup();
    private String          serviceAddress;
    private Integer         port;
    
    public ServerBootstrap config(IPeerContext context, Integer pid, String serviceAddress, int port, int timeout, int logLevel){
        this.serviceAddress = serviceAddress;
        this.port = port;
        //创建ServerBootstrap辅助类  客户端是Bootstrap辅助类 注意区分
        ServerBootstrap bootstrap = new ServerBootstrap();
        //通过辅助类配置通道参数
        bootstrap.group(boss, work);
        bootstrap.channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .option(ChannelOption.TCP_NODELAY, true)
//			.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 500)
			.option(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT)
            .childOption(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT)
            .childOption(ChannelOption.TCP_NODELAY, true)
            .childHandler(new ChannelInitializer<SocketChannel>() {
                //关联通道的处理类
                @Override
                protected void initChannel(SocketChannel sc) throws Exception {
                    //15分钟无读写事件，自动断连
                	sc.pipeline().addLast(new IdleStateHandler(0, 0, timeout, TimeUnit.MINUTES));
                    sc.pipeline().addLast("decoder",new Gate2HostDecoder(false, pid, logLevel, context));
                    sc.pipeline().addLast("encoder",new Host2GateEncoder(logLevel));
                    sc.pipeline().addLast(new ConnectorAsServer4GateInHandler());
            }
        });
        return bootstrap;
    }
    
    public void bindAddress(ServerBootstrap bootstrap) {
        ChannelFuture channelFuture = null;;
        try {
            channelFuture = bootstrap.bind(port);
            LogWorker.logForce(ConnectorContext.CONNECTOR_NAME + "已启动 port = " + port);
            
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            LogWorker.error(e.getMessage(), e);
        }finally{
        	close();
        	if (channelFuture != null) {
                channelFuture.channel().close();
        	}
        }
    }

    /**
     * 关闭服务
     */
    public void close(){
        CommonUtil.closeEventLoop(boss, work);
    }

	public String getLocalAddress() {
		return serviceAddress == null || port == null ? null : serviceAddress + ConstantValue.CONNECTOR_CHAR + port;
	}
}


